<template>
  <div class="my-applications">
    <div class="section-header">
      <h2>我的申请</h2>
      <div class="header-actions">
        <el-button type="primary" @click="refreshApplications">
          <el-icon><Refresh /></el-icon> 刷新列表
        </el-button>
        <el-button type="primary" @click="$emit('switch-to-browse')">继续申请</el-button>
      </div>
    </div>
    
    <div v-loading="loading" class="applications-list">
      <div v-if="!applications.length" class="empty-state">
        <el-empty description="暂无申请记录" />
      </div>
      <div v-else>
        <div v-for="app in applications" :key="app.applicationId" class="application-card">
          <div class="app-header">
            <div class="app-info">
              <h4>{{ app.clubName }}</h4>
              <p class="app-position">{{ app.recruitmentTitle }}</p>
            </div>
            <el-tag :type="getApplicationStatusStyle(app.status)" size="large">
              {{ getApplicationStatusText(app.status) }}
            </el-tag>
          </div>
          
          <div class="app-content">
            <p><strong>申请时间：</strong>{{ formatDateTime(app.createTime) }}</p>
            <p><strong>个人简介：</strong>{{ app.personalIntroduction }}</p>
            <p><strong>申请理由：</strong>{{ app.applicationReason }}</p>
            <p v-if="app.reviewTime"><strong>审核时间：</strong>{{ formatDateTime(app.reviewTime) }}</p>
            <p v-if="app.reviewComments"><strong>审核意见：</strong>{{ app.reviewComments }}</p>
            <p v-if="app.interviewTime"><strong>面试时间：</strong>{{ formatDateTime(app.interviewTime) }}</p>
            <p v-if="app.interviewLocation"><strong>面试地点：</strong>{{ app.interviewLocation }}</p>
          </div>
          
          <div class="app-actions">
            <el-button 
              v-if="app.status === '0'" 
              type="danger" 
              size="small"
              @click="handleWithdrawApplication(app.applicationId)"
            >
              撤回申请
            </el-button>
            <el-button 
              v-if="app.status === '1'" 
              type="primary" 
              size="small"
              @click="openInterviewBooking(app)"
            >
              预约面试
            </el-button>
            <el-button 
              v-if="app.status === '4' && app.interviewTime" 
              type="warning" 
              size="small"
              @click="openInterviewBooking(app)"
            >
              修改预约
            </el-button>
          </div>
        </div>
      </div>
    </div>

    <!-- 申请对话框 -->
    <el-dialog v-model="applyVisible" title="申请加入社团" width="500px">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="申请岗位" prop="recruitmentId">
          <el-select v-model="form.recruitmentId" placeholder="选择岗位" style="width: 100%" :loading="loading">
            <el-option 
              v-for="item in recruitmentList" 
              :key="item.recruitmentId" 
              :label="item.title || item.recruitmentTitle || item.positionName" 
              :value="item.recruitmentId"
            />
            <template #empty>
              <div style="padding: 12px; text-align: center; color: #999;">
                {{ recruitmentList.length === 0 ? '暂无可申请的岗位' : '无匹配数据' }}
              </div>
            </template>
          </el-select>
        </el-form-item>
        <el-form-item label="个人简介" prop="introduction">
          <el-input v-model="form.introduction" type="textarea" :rows="3" placeholder="简单介绍一下自己" />
        </el-form-item>
        <el-form-item label="申请理由" prop="reason">
          <el-input v-model="form.reason" type="textarea" :rows="2" placeholder="申请理由" />
        </el-form-item>
        <el-form-item label="联系电话" prop="phone">
          <el-input v-model="form.phone" placeholder="手机号码" />
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="applyVisible = false">取消</el-button>
        <el-button type="primary" @click="submitApplication" :loading="submitting">提交申请</el-button>
      </template>
    </el-dialog>

    <!-- 面试预约对话框 -->
    <el-dialog v-model="interviewVisible" :title="isUpdateInterview ? '修改面试预约' : '预约面试'" width="500px">
      <el-form ref="interviewFormRef" :model="interviewForm" :rules="interviewRules" label-width="100px">
        <el-form-item label="申请社团" prop="clubName">
          <el-input v-model="interviewForm.clubName" disabled />
        </el-form-item>
        <el-form-item label="申请岗位" prop="recruitmentTitle">
          <el-input v-model="interviewForm.recruitmentTitle" disabled />
        </el-form-item>
        <!-- 删除面试日期字段，将日期信息整合到时段中 -->
        <el-form-item label="可用时段" prop="selectedSlotId">
          <div v-if="loadingSlots" class="text-center py-4">
            <el-icon><Loading /></el-icon> 加载可用时段中...
          </div>
          <el-radio-group v-model="interviewForm.selectedSlotId" v-else class="slot-radio-group">
            <div v-if="availableSlots.length === 0" class="text-center py-4 text-gray-500">
              暂无可用面试时段
            </div>
            <div v-else class="slot-options">
              <el-radio
                v-for="slot in availableSlots"
                :key="slot.slotId"
                :label="slot.slotId"
                class="slot-option slot-radio"
              >
                <div class="slot-content">
                  <div class="slot-header">
                    <span class="slot-date">{{ slot.interviewDate }}</span>
                    <span class="slot-time">{{ slot.startTime }} - {{ slot.endTime }}</span>
                  </div>
                  <div class="slot-info">
                    <span class="info-item">地点：{{ slot.location }}</span>
                    <span class="info-item">面试官：{{ slot.interviewer }}</span>
                    <span class="info-item">剩余名额：{{ slot.availableCount || (slot.maxApplicants - slot.bookedCount) }}/{{ slot.maxApplicants }}</span>
                  </div>
                  <div v-if="slot.notes" class="slot-notes">{{ slot.notes }}</div>
                </div>
              </el-radio>
            </div>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="remarks">
          <el-input v-model="interviewForm.remarks" type="textarea" :rows="3" placeholder="如有特殊需求请说明" />
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button @click="interviewVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmInterviewBooking" :loading="bookingLoading">确认预约</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Document, Delete, Refresh } from '@element-plus/icons-vue'
import request from '@/utils/request'
import myApplicationsApi from '@/api/campus/student/myApplications'
import useUserStore from '@/store/modules/user'

// 使用解构赋值从默认导出中获取函数
const { 
  getStudentApplications,
  withdrawApplication: apiWithdrawApplication,
  submitApplication,
  bookInterview,
  updateInterview,
  getAvailableSlots
} = myApplicationsApi

// 由于API文件中没有cancelApplication，创建一个与withdrawApplication相同功能的函数
const apiCancelApplication = apiWithdrawApplication

const emit = defineEmits(['switch-to-browse', 'switch-to-interviews'])

// Props
const props = defineProps({
  currentUserId: {
    type: String,
    required: false,
    default: ''
  }
})

// Data
const loading = ref(false)
const applications = ref([])
const applyVisible = ref(false)
const formRef = ref(null)
const form = ref({
  recruitmentId: '',
  introduction: '',
  reason: '',
  phone: ''
})
const rules = ref({
  recruitmentId: [
    { required: true, message: '请选择申请岗位', trigger: 'change' }
  ],
  introduction: [
    { required: true, message: '请输入个人简介', trigger: 'blur' }
  ],
  reason: [
    { required: true, message: '请输入申请理由', trigger: 'blur' }
  ],
  phone: [
    { required: true, message: '请输入联系电话', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
  ]
})
const recruitmentList = ref([])
const submitting = ref(false)

// 面试预约相关数据
const interviewVisible = ref(false)
const bookingLoading = ref(false)
const loadingSlots = ref(false)
const interviewFormRef = ref(null)
const isUpdateInterview = ref(false)
const selectedApplication = ref(null)
const availableSlots = ref([])

// 面试预约表单数据
const interviewForm = reactive({
  clubName: '',
  recruitmentTitle: '',
  selectedSlotId: '',
  remarks: ''
})

// 面试预约表单验证规则
const interviewRules = reactive({
  selectedSlotId: [
    { required: true, message: '请选择面试时段', trigger: 'change' }
  ],
  remarks: [
    { max: 200, message: '备注长度不能超过200个字符', trigger: 'blur' }
  ]
})

// 从多个可能的位置获取用户ID的辅助函数
const getUserIdFromStorage = () => {
  // 打印所有localStorage键值对，调试用
  console.log('===== localStorage 内容分析 =====');
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    try {
      const value = localStorage.getItem(key);
      console.log(`localStorage[${key}]:`, value);
      
      // 特别检查用户相关的关键字段
      if (key.toLowerCase().includes('user') || 
          key.toLowerCase().includes('token') || 
          key.toLowerCase().includes('auth')) {
        console.log(`🚨 可能包含用户信息的字段: ${key}`);
        // 尝试解析为对象
        try {
          const parsed = JSON.parse(value);
          console.log(`解析后内容:`, parsed);
        } catch (e) {
          console.log(`不是JSON格式`);
        }
      }
    } catch (e) {
      console.log(`读取 ${key} 时出错:`, e);
    }
  }
  console.log('==================================');

  // 尝试从所有可能的位置获取用户ID
  let userId = '';
  
  // 1. 尝试从常见的用户ID字段获取
  const userIdKeys = ['userId', 'id', 'user_id', 'username', 'loginName', 'account'];
  for (const key of userIdKeys) {
    const value = localStorage.getItem(key);
    if (value && value.trim()) {
      userId = value;
      console.log(`1. 从 ${key} 获取到用户ID:`, userId);
      break;
    }
  }
  
  // 2. 尝试从userInfo对象中获取各种可能的用户ID字段
  if (!userId) {
    try {
      const userInfoStr = localStorage.getItem('userInfo') || localStorage.getItem('userinfo');
      if (userInfoStr) {
        const userInfo = JSON.parse(userInfoStr);
        console.log('发现userInfo对象:', userInfo);
        
        // 尝试所有可能的用户ID字段名
        const possibleIdFields = ['id', 'userId', 'user_id', 'username', 'loginName', 'account', 'studentId'];
        for (const field of possibleIdFields) {
          if (userInfo[field] && String(userInfo[field]).trim()) {
            userId = String(userInfo[field]);
            console.log(`2. 从userInfo.${field}获取到用户ID:`, userId);
            break;
          }
        }
      }
    } catch (e) {
      console.warn('解析userInfo失败:', e);
    }
  }
  
  // 3. 尝试从token或其他认证信息中获取
  if (!userId) {
    try {
      const tokenKeys = ['token', 'Authorization', 'auth_token', 'access_token'];
      let token = '';
      
      for (const key of tokenKeys) {
        token = localStorage.getItem(key);
        if (token) break;
      }
      
      if (token) {
        console.log('发现token:', token);
        // 简单尝试解码token前半部分
        try {
          const tokenParts = token.split('.');
          if (tokenParts.length >= 2) {
            const decoded = JSON.parse(atob(tokenParts[1].replace(/-/g, '+').replace(/_/g, '/')));
            console.log('token解码内容:', decoded);
            
            // 尝试所有可能的用户ID字段名
            const possibleIdFields = ['id', 'userId', 'user_id', 'username', 'loginName', 'account', 'sub', 'name'];
            for (const field of possibleIdFields) {
              if (decoded[field] && String(decoded[field]).trim()) {
                userId = String(decoded[field]);
                console.log(`3. 从token.${field}获取到用户ID:`, userId);
                break;
              }
            }
          }
        } catch (e) {
          console.warn('解码token失败:', e);
        }
      }
    } catch (e) {
      console.warn('从token获取用户ID失败:', e);
    }
  }
  
  return userId;
};

const getApplicationStatusStyle = (status) => {
  const statusStyleMap = {
    '0': 'info',      // 待审核
    '1': 'success',   // 已通过
    '2': 'danger',    // 已拒绝
    '3': 'warning',   // 已撤回
    '4': 'primary'    // 待面试
    // 可以根据实际业务需求扩展其他状态
  };
  return statusStyleMap[status] || 'default';
};

const getApplicationStatusText = (status) => {
  const statusTextMap = {
    '0': '待审核',
    '1': '已通过',
    '2': '已拒绝',
    '3': '已撤回',
    '4': '待面试'
    // 可以根据实际业务需求扩展其他状态
  };
  return statusTextMap[status] || '未知状态';
};

const formatDateTime = (dateTimeString) => {
  if (!dateTimeString) return '';
  
  try {
    const date = new Date(dateTimeString);
    if (isNaN(date.getTime())) return dateTimeString; // 如果日期无效，返回原始字符串
    
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    const hours = String(date.getHours()).padStart(2, '0');
    const minutes = String(date.getMinutes()).padStart(2, '0');
    
    return `${year}-${month}-${day} ${hours}:${minutes}`;
  } catch (error) {
    console.warn('日期格式化失败:', error);
    return dateTimeString;
  }
};

// 从applicationContent中提取个人简介和申请理由
const extractApplicationDetails = (application) => {
  // 如果已经有单独的字段，直接返回
  if (application.personalIntroduction && application.applicationReason) {
    return {
      personalIntroduction: application.personalIntroduction,
      applicationReason: application.applicationReason
    };
  }
  
  // 从applicationContent中提取信息
  const content = application.applicationContent || '';
  let personalIntroduction = '';
  let applicationReason = '';
  
  // 匹配个人简介部分
  const introMatch = content.match(/个人简介：([\s\S]*?)\n\n/);
  if (introMatch && introMatch[1]) {
    personalIntroduction = introMatch[1].trim();
  }
  
  // 匹配申请理由部分
  const reasonMatch = content.match(/申请理由：([\s\S]*?)\n\n/);
  if (reasonMatch && reasonMatch[1]) {
    applicationReason = reasonMatch[1].trim();
  }
  
  return {
    personalIntroduction,
    applicationReason
  };
};

// 获取有效的用户ID（优先使用store，其次是props，最后是localStorage）
const getValidUserId = computed(() => {
  // 1. 从store获取用户ID（最高优先级）
  try {
    const userStore = useUserStore();
    if (userStore && userStore.id) {
      console.log('从store获取到用户ID:', userStore.id);
      return String(userStore.id).trim();
    }
  } catch (error) {
    console.warn('获取store用户信息失败:', error);
  }
  
  // 2. 从props获取userId
  const userIdFromProps = String(props.currentUserId || '').trim();
  console.log('props中的用户ID:', userIdFromProps);
  
  // 3. 检查localStorage中的userId
  const userIdFromStorage = getUserIdFromStorage();
  
  // 使用第一个有效的用户ID
  const validUserId = userIdFromProps || userIdFromStorage;
  
  console.log('最终有效用户ID:', validUserId);
  return validUserId;
});

// 禁用过去的日期
const disablePastDates = (time) => {
  return time.getTime() < Date.now() - 8.64e7; // 禁用今天之前的日期（包括今天）
};

const loadApplications = async () => {
  const validUserId = getValidUserId.value;
  
  if (!validUserId || validUserId === 'undefined' || validUserId === 'null' || validUserId.trim() === '') {
    console.warn('用户ID为空，无法加载申请信息');
    ElMessage.warning('请先登录后再操作');
    return;
  }
  
  console.log('使用用户ID加载申请信息:', validUserId);
  
  loading.value = true;
  try {
    // 尝试不同的API调用方式，确保传递正确的参数格式
    let response;
    try {
      // 第一种方式：直接传递用户ID
      response = await getStudentApplications(validUserId);
    } catch (e) {
      // 第二种方式：以对象形式传递用户ID
      console.log('尝试以对象形式传递用户ID');
      response = await getStudentApplications({ userId: validUserId });
    }
    
    if (response.code === 200) {
      // 原始申请数据
      const rawApplications = response.data || [];
      console.log('加载到的申请数量:', rawApplications.length);
      
      // 处理每个申请，提取个人简介和申请理由
      applications.value = rawApplications.map(app => {
        // 提取详细信息
        const details = extractApplicationDetails(app);
        
        // 返回新对象，包含原始字段和提取的字段
        return {
          ...app,
          personalIntroduction: details.personalIntroduction,
          applicationReason: details.applicationReason,
          // 如果recruitmentTitle为空，尝试其他可能的字段
          recruitmentTitle: app.recruitmentTitle || app.positionName || app.title || ''
        };
      });
      
      console.log('处理后的申请数据:', applications.value);
      
      // 如果没有数据，提示用户
      if (applications.value.length === 0) {
        ElMessage.info('您还没有提交任何申请');
      }
    } else {
      console.warn('获取申请信息失败:', response.msg);
      applications.value = [];
      ElMessage.warning(response.msg || '获取申请信息失败');
    }
  } catch (error) {
    console.error('加载申请信息失败:', error);
    ElMessage.error('网络错误，请稍后重试');
    applications.value = [];
  } finally {
    loading.value = false;
  }
}

const refreshApplications = () => {
  loadApplications();
}

const handleCancelApplication = async (applicationId) => {
  try {
    await ElMessageBox.confirm('确定要取消这个申请吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });
    
    const response = await apiCancelApplication(applicationId);
    if (response.code === 200) {
      ElMessage.success('申请已取消');
      loadApplications();
    } else {
      ElMessage.error(response.msg || '取消失败');
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('取消申请失败:', error);
      ElMessage.error('网络错误，请稍后重试');
    }
  }
}

const handleWithdrawApplication = async (applicationId) => {
  try {
    await ElMessageBox.confirm('确定要撤回这个申请吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });
    
    const response = await apiWithdrawApplication(applicationId);
    if (response.code === 200) {
      ElMessage.success('申请已撤回');
      loadApplications();
    } else {
      ElMessage.error(response.msg || '撤回失败');
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('撤回申请失败:', error);
      ElMessage.error('网络错误，请稍后重试');
    }
  }
}

const viewApplicationDetails = (application) => {
  // 查看申请详情的逻辑
  console.log('查看申请详情:', application);
}

// 获取可用面试时段
const fetchAvailableSlots = async (recruitmentId) => {
  if (!recruitmentId) {
    availableSlots.value = [];
    return;
  }
  
  loadingSlots.value = true;
  try {
    // 调用API获取可用时段
    const res = await getAvailableSlots(recruitmentId);
    if (res.code === 200) {
      availableSlots.value = res.data || [];
    } else {
      ElMessage.error('获取可用面试时段失败');
      availableSlots.value = [];
    }
  } catch (error) {
    console.error('获取可用面试时段失败:', error);
    // 不显示错误消息，静默使用模拟数据
    // 提供基础的模拟数据作为备用
    availableSlots.value = [
      {
        slotId: '1',
        interviewDate: '2023-10-25',
        startTime: '10:00',
        endTime: '11:00',
        location: '活动中心会议室A',
        interviewer: '张老师',
        availableCount: 2,
        maxApplicants: 3,
        notes: '请提前10分钟到达'
      },
      {
        slotId: '2',
        interviewDate: '2023-10-25',
        startTime: '14:00',
        endTime: '15:00',
        location: '活动中心会议室B',
        interviewer: '李老师',
        availableCount: 1,
        maxApplicants: 2,
        notes: ''
      },
      {
        slotId: '3',
        interviewDate: '2023-10-26',
        startTime: '16:00',
        endTime: '17:00',
        location: '学生活动中心201',
        interviewer: '王老师',
        availableCount: 3,
        maxApplicants: 3,
        notes: '适合计算机相关岗位'
      }
    ];
  } finally {
    loadingSlots.value = false;
  }
};

const openInterviewBooking = (application) => {
  selectedApplication.value = application;
  
  // 设置表单初始数据
  interviewForm.clubName = application.clubName || '';
  interviewForm.recruitmentTitle = application.recruitmentTitle || '';
  interviewForm.selectedSlotId = '';
  interviewForm.remarks = '';
  
  availableSlots.value = [];
  isUpdateInterview.value = false;
  
  // 如果已有面试时间和预约信息，可以尝试加载相关时段
  if (application.interviewTime && application.appointmentId) {
    isUpdateInterview.value = true;
    // 这里可以根据需要实现更新预约的逻辑
  }
  
  // 获取可用面试时段
  if (application.recruitmentId) {
    fetchAvailableSlots(application.recruitmentId);
  }
  
  // 打开对话框
  interviewVisible.value = true;
};

const confirmInterviewBooking = async () => {
  // 验证申请状态
  if (selectedApplication.value.status !== '1' && selectedApplication.value.status !== '4') {
    ElMessage.error('只有审核通过的申请才能预约面试');
    return;
  }
  
  // 验证表单
  if (!interviewFormRef.value) {
    ElMessage.warning('表单引用未初始化');
    return;
  }
  
  try {
    await interviewFormRef.value.validate();
  } catch (error) {
    ElMessage.warning('请检查表单填写是否正确');
    return;
  }
  
  // 确保selectedApplication存在
  if (!selectedApplication.value) {
    ElMessage.warning('未选择要预约的申请');
    return;
  }
  
  // 找到选中的时段
  const selectedSlot = availableSlots.value.find(slot => slot.slotId === interviewForm.selectedSlotId);
  if (!selectedSlot) {
    ElMessage.warning('请选择有效的面试时段');
    return;
  }
  
  // 准备提交数据
  const bookingData = {
    applicationId: selectedApplication.value.applicationId || '',
    studentId: getValidUserId.value,
    slotId: selectedSlot.slotId,
    interviewTime: `${selectedSlot.interviewDate} ${selectedSlot.startTime}`,
    interviewLocation: selectedSlot.location,
    remarks: interviewForm.remarks,
    status: '4' // 待面试状态
  };
  
  // 如果是更新预约，确保包含appointmentId
  if (isUpdateInterview.value && selectedApplication.value.appointmentId) {
    bookingData.appointmentId = selectedApplication.value.appointmentId;
  }
  
  console.log('提交面试预约数据:', bookingData);
  
  bookingLoading.value = true;
  try {
    let response;
    
    if (isUpdateInterview.value) {
      response = await updateInterviewAppointment(bookingData);
    } else {
      response = await bookInterview(bookingData);
    }
    
    if (response.code === 200) {
      ElMessage.success(isUpdateInterview.value ? '面试预约已更新' : '面试预约成功');
      interviewVisible.value = false;
      // 更新申请表单状态为待面试
      selectedApplication.value.status = '4';
      // 更新面试信息
      selectedApplication.value.interviewTime = bookingData.interviewTime;
      selectedApplication.value.interviewLocation = bookingData.interviewLocation;
      // 刷新申请列表
      loadApplications();
    } else {
      ElMessage.error(response.msg || '预约失败');
    }
  } catch (error) {
    console.error('面试预约失败:', error);
    // 改进错误处理，显示更具体的错误信息
    if (error.response && error.response.data && error.response.data.msg) {
      ElMessage.error(error.response.data.msg);
    } else {
      ElMessage.error('网络错误，请稍后重试');
    }
  } finally {
    bookingLoading.value = false;
  }
};

// 监听用户ID变化
watch(() => props.currentUserId, (newUserId) => {
  // 即使props没有变化，也尝试从localStorage获取用户ID
  loadApplications();
})

// Initialize
onMounted(() => {
  // 无论props中是否有用户ID，都尝试加载数据（会从localStorage获取）
  loadApplications();
})

// Expose methods for parent component
defineExpose({
  loadApplications,
  refreshApplications
})
</script>

<style scoped>
.my-applications {
  max-width: 1200px;
  margin: 0 auto;
  padding: 30px 20px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.section-header h2 {
  margin: 0;
  color: #303133;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.application-card {
  background: white;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 16px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.app-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
}

.app-info h4 {
  margin: 0 0 4px;
  color: #303133;
}

.app-position {
  margin: 0;
  color: #606266;
  font-size: 14px;
}

.app-content {
  margin-bottom: 16px;
}

.app-content p {
  margin: 8px 0;
  color: #606266;
}

.app-actions {
  text-align: right;
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.empty-state {
  padding: 40px 0;
  text-align: center;
}


.app-info h4 {
  margin: 0 0 4px;
  color: #303133;
}

.app-position {
  margin: 0;
  color: #909399;
  font-size: 14px;
}

.app-content {
  margin-bottom: 12px;
}

.app-content p {
  margin: 8px 0;
  color: #606266;
}

.app-actions {
  display: flex;
  gap: 8px;
}

.empty-state {
  text-align: center;
  padding: 40px 0;
}

/* 可用时段样式 */
.slot-radio-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.slot-radio {
  width: 100%;
  margin-bottom: 0;
}

.slot-radio .el-radio__label {
  width: 100%;
  padding: 16px;
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  transition: all 0.3s ease;
  cursor: pointer;
  display: block;
}

.slot-radio .el-radio__label:hover {
  border-color: #409eff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  background-color: #f5f7fa;
}

.slot-radio.is-checked .el-radio__label {
  border-color: #409eff;
  background-color: #ecf5ff;
}

.slot-content {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.slot-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.slot-date {
  font-size: 14px;
  color: #606266;
  font-weight: 500;
}

.slot-time {
  font-size: 16px;
  font-weight: bold;
  color: #409eff;
}

.slot-info {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
}

.info-item {
  font-size: 14px;
  color: #606266;
}

.slot-notes {
  font-size: 13px;
  color: #909399;
  font-style: italic;
  margin-top: 4px;
}

.slot-loading,
.no-slots {
  padding: 30px 0;
}

.slots-container {
  margin-top: 10px;
}
</style>
